package core.genetico;

import java.util.Random;

import core.exception.GeneticoException;



public class OperadorGenetico {

	private static double taxaMutacao = 0.1;
	private static Random aleatorio = new Random();
	private static int numeroCromossomos = 1;

	public static String[] crossover(String codigo1, String codigo2) throws GeneticoException{	
		if(numeroCromossomos > codigo1.length())
			throw new GeneticoException("O número de cromossomos é maior que o tamanho do código");
		if(codigo1.length() != codigo2.length())
			throw new GeneticoException("O tamanho das duas cadeias deve ser igual");
		int tamanhoCromossomo, resto, i;
		tamanhoCromossomo = codigo1.length()/numeroCromossomos;
		resto = codigo1.length()%numeroCromossomos;
		StringBuilder filho1 = new StringBuilder(), filho2 = new StringBuilder();
		String[] cromossomoResultante = new String[2], filhos = new String[2];
		for(i=0; i<numeroCromossomos -1; i++){
			cromossomoResultante = crossoverCromossomo(
					codigo1.substring(i*tamanhoCromossomo, (i+1)*tamanhoCromossomo),
					codigo2.substring(i*tamanhoCromossomo, (i+1)*tamanhoCromossomo));
			filho1.append(cromossomoResultante[0]);
			filho2.append(cromossomoResultante[1]);
		}
		cromossomoResultante = crossoverCromossomo(
				codigo1.substring(i*tamanhoCromossomo),
				codigo2.substring(i*tamanhoCromossomo));
		filho1.append(cromossomoResultante[0]);
		filho2.append(cromossomoResultante[1]);
		filhos[0] = filho1.toString();
		filhos[1] = filho2.toString();
		return filhos;
	}

	private static String[] crossoverCromossomo(String cromossomo1,String cromossomo2) {
		StringBuilder sb = new StringBuilder();
		int crossPoint = aleatorio.nextInt(cromossomo1.length()/2 + 1);
		int crossPoint2 = crossPoint + cromossomo1.length()/2;
		String filhos[] = new String[2];
		sb = new StringBuilder();
		sb.append(cromossomo1.substring(0, crossPoint));
		sb.append(cromossomo2.substring(crossPoint, crossPoint2));
		sb.append(cromossomo1.substring(crossPoint2));
		filhos[0] = sb.toString();
		sb = new StringBuilder();
		sb.append(cromossomo2.substring(0, crossPoint));
		sb.append(cromossomo1.substring(crossPoint, crossPoint2));
		sb.append(cromossomo2.substring(crossPoint2));	
		filhos[1] = sb.toString();
		return filhos;
	}

	public static String mutacao(String codigo){
		StringBuilder sb = new StringBuilder();
		int i;
		for(i = 0; i < codigo.length(); i++){
			if(aleatorio.nextDouble() < taxaMutacao){
				if(codigo.charAt(i) == '0')
					sb.append('1');
				else
					sb.append('0');
			}
			else
				sb.append(codigo.charAt(i));
		}
		return sb.toString();
	}

}
